понедельник, 17 ноября 2014 г.

LDAP запрос используя Kerberos аутентификацию на Apache + PHP

Исходно есть CentOS 6.5 minimal.
Kerberos, LDAP построены на Microsoft Server 2012.

Настройка Microsoft Server 2012.

DNS
Создаем запись в DNS
 

 Active Directory
Создаем учетную запись для веб-сервера, и разрешаем делегирование


Генерируем keytab файл
C:\>ktpass -princ HTTP/web-server.domain.ru@DOMAIN.RU -mapuser domain\WEB-SERVER -crypto RC4-HMAC-NT -ptype KRB5_NT_PRINCIPAL -mapop set -pass Pa$$W0rdd -out c:\temp\krb5.keytab

Targeting domain controller: DOMAIN-CTRL.DOMAIN.RU WARNING: Account WEB-SERVER$ is not a normal user account (uacFlags=0x1020).

Do you really want to delete any previous servicePrincipalName values on WEB-SERVER$ [y/n]?  y
Successfully mapped HTTP/web-server.domain.ru to WEB-SERVER$.
WARNING: Resetting WEB-SERVER$'s password may cause authentication problems if WEB-SERVER$ is being used as a server.

Reset WEB-SERVER$'s password [y/n]?  y
Password successfully set!
WARNING: pType and account type do not match. This might cause problems.
Key created.
Output keytab to c:\temp\krb5.keytab:
Keytab version: 0x502
keysize 77 HTTP/web-server.domain.ru@DOMAIN.RU ptype 1 (KRB5_NT_PRINCIPAL) vno 1 etype 0x17 (RC4-HMAC) keylength 16 (0x7421eb4f97fc28fddfcd548849196da7)

И проверяем, что привязка выполена корректно
C:\>setspn -q HTTP/web-server.domain.ru
Checking domain DC=DOMAIN,DC=RU
CN=WEB-SERVER,OU=SERVERS,DC=
DOMAIN,DC=RU
        HTTP/web-server.domain.ru


Existing SPN found!

  

Настройка CentOS

Selinux и iptables отключены, так как здесь не рассматриваются.

Настраиваем корректно ip и имя хоста.
vi /etc/sysconfig/network-scripts/ifcfg-eth0
vi /etc/sysconfig/network
vi /etc/hosts

В моем случае web-server.domain.ru (10.0.0.242)

Установка remi репозитория
rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

Установка Apache и PHP
yum --enablerepo=remi install httpd php php-ldap

chkconfig httpd on


Установка Kerberos и механизм SASL GSSAPI.
yum install krb5-workstation krb5-devel krb5-libs mod_auth_kerb cyrus-sasl-gssapi

Настойка Kerberos
vi /etc/krb5.conf
[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 default_realm = DOMAIN.RU
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true

[realms]
 DOMAIN.RU = {
  kdc = domain-ctrl.domain.ru
  admin_server = domain-ctrl.domain.ru
 }

[domain_realm]
 web-server.domain.ru = DOMAIN.RU

Настройка LDAP. Для продуктовой системы лучше правильно настроить сертификаты  и установить TLS_REQCERT hard, но в моем случае это не имеет значения.
vi /etc/openldap/ldap.conf
TLS_REQCERT never

Скопировать полученный keytab файл с контроллера домена на web-server в /etc/httpd/conf/. Например с помощью WinSCP.

Получаем исходный ticket-granting ticket, используя keytab файл
kinit -k -t /etc/httpd/conf/krb5.keytab HTTP/web-server.domain.ru

Проверяем правильность полученых данный
[root@web-server ~]# kvno HTTP/web-server.domain.ru@DOMAIN.RU
HTTP/web-server.domain.ru@DOMAIN.RU: kvno = 1
[root@web-server ~]# klist -e
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: HTTP/web-server.domain.ru@DOMAIN.RU

Valid starting     Expires            Service principal
11/17/14 15:26:44  11/18/14 15:26:44  krbtgt/DOMAIN.RU@DOMAIN.RU renew until 11/24/14 15:26:44, Etype (skey, tkt): arcfour-hmac, arcfour-hmac
11/17/14 15:27:18  11/18/14 01:27:18  HTTP/web-server.domain.ru@DOMAIN.RU renew until 11/24/14 15:26:44, Etype (skey, tkt): arcfour-hmac, arcfour-hmac 

Проверить что есть появился файл, и в нем подгружается модуль Kerberos
vi /etc/httpd/conf.d/auth_kerb.conf
LoadModule auth_kerb_module modules/mod_auth_kerb.so

Настройка Apache
Добавоить в /etc/httpd/conf/httpd.conf

ServerName web-server.domain.ru:80

<Directory "/var/www/html">
    AuthType  Kerberos
    KrbAuthRealms DOMAIN.RU
    KrbServiceName HTTP/web-server.domain.ru
    Krb5Keytab /etc/httpd/conf/krb5.keytab
    KrbMethodNegotiate on
    KrbMethodK5Passwd on
    require valid-user
    KrbLocalUserMapping on
    KrbSaveCredentials on
</Directory>
Здесь важной директивой является KrbSaveCredentials on, без нее в PHP не будет создаваться переменная $_SERVER['KRB5CCNAME'], а без нее аутентификация LDAP работать не будет (в логах будет только GSSAPI Local Error).

service httpd restart

Проверочный скрипт
<?php
    var_dump($_SERVER['PHP_AUTH_USER']);
    echo('<br/>');
    var_dump($_SERVER['KRB5CCNAME']);

    putenv("KRB5CCNAME={$_SERVER['KRB5CCNAME']}");

    $ldapconn = ldap_connect('domain-ctrl.domain.ru', 389) or die('error connect с $ldaphost');
    ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
    ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);

    $result = ldap_sasl_bind($ldapconn, NULL, NULL, 'GSSAPI', 'DOMAIN.RU', '', '')  or die('Failed to GSSAPI bind.');

    $result = ldap_search($ldapconn, 'DC=DOMAIN,DC=RU', '(samaccountname='.$_SERVER['PHP_AUTH_USER'].')', array('cn', 'description', 'telephonenumber', 'mail'));
    $result_entries = ldap_get_entries($ldapconn, $result);
    echo '<pre>';
    var_dump($result_entries);
    echo '</pre>';
?>

Для IE: Внутри сети сервер должен относится к зоне безопасности "Местная интрасеть"
И должна быть включена опция "Проверка подлинности пользователя" -> "Вход" -> "Автоматический вход в сеть только в зоне интрасети".

Результат скрипта


Настройка браузеров

Internet Explorer
Узел должен определяться в зоне местной интрасети и зона должна иметь разрешение на проверку подлинности


Firefox

Открыть новую вкладку. Ввести about:config. В поиске набрать negotiate. Вписать домен в доверенные

Chrome

Добавить в реестр

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]
"AuthNegotiateDelegateWhitelist"="*.domain.ru"
"AuthServerWhitelist"="*.domain.ru"

8 комментариев:

  1. Аутентификация проходит, а переменная Krb5ccname не устанавливается,в чем может быть проблема?

    ОтветитьУдалить
    Ответы
    1. Т.е. проверочный скрипт отрабатывает, а переменной нет?

      Удалить
    2. Имя пользователя есть, а krb5ccname нет

      Удалить
    3. В httpd.conf есть KrbSaveCredentials on?
      А браузер какой? С настройками по-умолчанию работает только IE (должен быть установлен параметр Проверка подлинности пользователя - Автоматический вход).
      Для FF надо настроить два параметра network.negotiate-auth.trusted-uris и network.negotiate-auth.delegation-uris (https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/5/html/Deployment_Guide/sso-config-firefox.html)
      Для Chrome(для последних версий) надо добавить в реестр
      [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]
      "AuthNegotiateDelegateWhitelist"="*.domain.ru"
      "AuthServerWhitelist"="*.domain.ru"

      Удалить
  2. Спасибо огромное,вы мне очень помогли)

    ОтветитьУдалить
  3. Прошел год и я снова пытаюсь реализовать данный функционал,выходит такая ошибка:
    ldap_sasl_bind(): Unable to bind to server: Local error in

    ОтветитьУдалить
  4. Спасибо огромнейшее. Настройка оказалось достаточно простой)
    Хотя когда вникаешь в эту тему - кажется, что это какие-то космические технологии...

    ОтветитьУдалить
  5. Добрый день
    получаю вот такую ошибку
    string(30) "FILE:/tmp/krb5cc_apache_YPigR6" Failed to GSSAPI bind.
    В чем беда?

    ОтветитьУдалить